home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 408_01 / snews.c < prev    next >
Text File  |  1993-08-06  |  44KB  |  1,565 lines

  1. /*
  2.     SNEWS 1.91
  3.  
  4.     snews - a simple threaded news reader
  5.  
  6.  
  7.     Copyright (C) 1991  John McCombs, Christchurch, NEW ZEALAND
  8.                         john@ahuriri.gen.nz
  9.                         PO Box 2708, Christchurch, NEW ZEALAND
  10.  
  11.     Modifications copyright (C) 1993  Daniel Fandrich
  12.                         <dan@fch.wimsey.bc.ca> or CompuServe 72365,306
  13.  
  14.     This program is free software; you can redistribute it and/or modify
  15.     it under the terms of the GNU General Public License, version 1, as
  16.     published by the Free Software Foundation.
  17.  
  18.     This program is distributed in the hope that it will be useful,
  19.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.     GNU General Public License for more details.
  22.  
  23.     See the file COPYING, which contains a copy of the GNU General
  24.     Public License.
  25.  
  26.  
  27.     Source is formatted with a tab size of 4.
  28.  */
  29.  
  30. #include "defs.h"
  31. #include "snews.h"
  32. #include "pccharst.h"
  33. #include "getopt.h"
  34. #include <alloc.h>
  35. #include <ctype.h>
  36. #include <process.h>
  37.  
  38. unsigned _stklen = 8192;        /* default 4k stack can give problems */
  39.  
  40. INFO my_stuff;
  41.  
  42. /*------------------------------- main --------------------------------*/
  43. int main(int argc, char *argv[])
  44. {
  45.     ACTIVE *gp, *head;
  46.     int done, option;
  47.     int verbose = 1, errflag = 0;
  48.  
  49.     signal(SIGINT, sig_break);        /* turn control-break off */
  50.  
  51.     if (getenv("BIOSVIDEO") ||
  52.        (getenv("TERM") && (stricmp(getenv("TERM"), "pcbios") == 0)))
  53.         directvideo = 0;
  54.  
  55.     select_code_page();
  56.  
  57.     while ((option = getopt(argc, argv, "bqv?")) != -1)
  58.         switch (option) {
  59.             case 'b':        /* bios video output */
  60.                 directvideo = 0;
  61.                 break;
  62.  
  63.             case 'q':        /* quiet mode */
  64.                 verbose = 0;
  65.                 break;
  66.  
  67.             case 'v':        /* verbose mode */
  68.                 ++verbose;
  69.                 break;
  70.  
  71.             case '?':        /* display help */
  72.                 ++errflag;
  73.                 break;
  74.         };
  75.  
  76.     if ((argc > 1) && (argv[1][0] == '/'))
  77.         ++errflag;
  78.  
  79.     if (verbose)
  80.         printf(VERSION "\n"
  81.             "type snews -? for usage\n\n");
  82.     if ((verbose >= 2) || errflag)
  83.         printf(
  84.          "Copyright (C) 1991  John McCombs\n"
  85.          "Copyright (C) 1992  Michael Studte/John Dennis (Shinohara Industries)\n"
  86.          "Copyright (C) 1992  Kai Uwe Rommel\n"
  87.          "Copyright (C) 1993  Daniel Fandrich\n\n"
  88.  
  89.          "SNEWS comes with ABSOLUTELY NO WARRANTY.\n"
  90.          "This is free software, and you are welcome to redistribute it\n"
  91.          "under certain conditions; see the file COPYING for details.\n\n");
  92.  
  93.     if (errflag) {
  94.         printf(
  95.             "usage: snews [-q] [-v] [-b]\n"
  96.             "  -q  set quiet mode\n"
  97.             "  -v  set verbose mode\n"
  98.             "  -b  use BIOS for video output\n"
  99.         );
  100.         return 2;
  101.     }
  102.  
  103.     if (verbose)
  104.         printf("loading config... ");
  105.     if (load_stuff()) {
  106.  
  107.         if (verbose)
  108.             printf("loading active... ");
  109.         head = load_active_file();
  110.         if (verbose)
  111.             printf("loading read list... ");
  112.         load_read_list();
  113.         if (verbose)
  114.             printf("loading history... ");
  115.         load_history_list();
  116.  
  117.         done = FALSE;
  118.         gp = NULL;
  119.  
  120.         while (!done) {
  121.             if ((gp = select_group(head, gp)) != NULL) {
  122.                 done |= read_group(gp);
  123.             } else {
  124.                 done = TRUE;
  125.             }
  126.         }
  127.  
  128.         clrscr();
  129.  
  130.         free_hist_list();
  131.         if (verbose)
  132.             printf("writing read list... ");
  133.         save_read_list();
  134.         if (verbose)
  135.             printf("done\n");
  136.         close_active_file();
  137.     } else {
  138.         fprintf(stderr, "Couldn't find neccessary item in the .rc files\n");
  139.         return 2;
  140.     }
  141.     return 0;
  142. }
  143.  
  144.  
  145.  
  146.  
  147. /*-------------------------- find which group to read -----------------------*/
  148. ACTIVE *select_group(ACTIVE *head, ACTIVE *current)
  149. {
  150.     /*
  151.      *  Present the list of groups, and allow him to move up and down with
  152.      *  the arrow and PgUp and PgDn keys.  'h' for help, -/+ for searches
  153.      */
  154.  
  155.     ACTIVE *top;        /* newsgroup at the top of the page */
  156.     ACTIVE *this;       /* current newsgroup                */
  157.     ACTIVE *tmp_ng;
  158.     enum exit_codes exit_code;   /* why we are exiting the loop      */
  159.     char   sub_tmp[80];
  160.  
  161.     int    i, j, articles, unread;
  162.  
  163.     this = (current == NULL) ? head : current;
  164.  
  165.     top = head;
  166.     exit_code = EX_CONT;
  167.  
  168.     show_groups(&top, this, TRUE);
  169.  
  170.     while (exit_code == EX_CONT) {
  171.  
  172.         switch (get_any_key()) {
  173.  
  174.                     case Fn1    :
  175.                     case '?'    :
  176.                     case 'h'    :
  177.                         show_help(HELP_GROUP);
  178.                         show_groups(&top, this, TRUE);
  179.                         break;
  180.  
  181.                     case Fn2    :
  182.                         show_values();
  183.                         show_groups(&top, this, TRUE);
  184.                         break;
  185.  
  186.                     case UP_ARR :
  187.                         if (this->last != NULL) this = this->last;
  188.                         break;
  189.  
  190.                     case DN_ARR :
  191.                         if (this->next != NULL) this = this->next;
  192.                         break;
  193.  
  194.                     case PGUP   :
  195.                         for (i = 0; i < PAGE_LENGTH; i++) {
  196.                             if (this->last == NULL) break;
  197.                             this = this->last;
  198.                         }
  199.                         break;
  200.  
  201.                     case PGDN   :
  202.                         for (i = 0; i < PAGE_LENGTH; i++) {
  203.                             if (this->next == NULL) break;
  204.                             this = this->next;
  205.                         }
  206.                         break;
  207.  
  208.                     case '1'    :
  209.                     case HOME   :
  210.                         top = this = head;
  211.                         show_groups(&top, this, TRUE);
  212.                         break;
  213.  
  214.                     case '$'    :
  215.                     case END    :
  216.                         this = head;
  217.                         while (this->next != NULL)
  218.                             this = this->next;
  219.                         show_groups(&top, this, TRUE);
  220.                         break;
  221.  
  222.             case '/'    :
  223.             case '+'    :
  224.                 this = search_groups(this);
  225.                 break;
  226.  
  227.             case 'p'    :
  228.                 strcpy(sub_tmp, "");
  229.                 post(NULL, this->group, sub_tmp);
  230.                 show_groups(&top, this, TRUE);
  231.                 break;
  232.  
  233.             case 'c'    :
  234.                 mark_group_as_read(this);
  235.                 show_groups(&top, this, TRUE);
  236.                 break;
  237.  
  238.             case ' '    :
  239.             case 'n'    :
  240.             case TAB    :
  241.                 tmp_ng = this->next;
  242.                 unread = 0;
  243.                 while (tmp_ng != NULL) {
  244.                     articles = (int) (tmp_ng->hi_num - tmp_ng->lo_num);
  245.                     for (j = 0; j < articles; j++) {
  246.                         if ( *((tmp_ng->read_list)+j) == FALSE)
  247.                             unread++;
  248.                     }
  249.                     if (unread > 0) break;
  250.                     tmp_ng = tmp_ng->next;
  251.                 }
  252.                 if (unread > 0) {
  253.                     this = tmp_ng;
  254.                 } else {
  255.                     message("-- No more articles to read --");
  256.                 }
  257.                 break;
  258.  
  259.             case '!'    :
  260.                 textbackground(BLACK);    textcolor(LIGHTGRAY);
  261.                 cprintf("\r\n");
  262.                 spawnl(P_WAIT, getenv("COMSPEC"), getenv("COMSPEC"), NULL);
  263.                 show_groups(&top, this, TRUE);
  264.                 break;
  265.  
  266.             case ENTER  :
  267.                 exit_code = EX_DONE;
  268.                 break;
  269.  
  270.             case 'q'    :
  271.             case ESCAPE :
  272.                 exit_code = EX_QUIT;
  273.                 break;
  274.         };
  275.         if (exit_code == EX_CONT)
  276.             show_groups(&top, this, FALSE);
  277.     }
  278.  
  279.     if (exit_code == EX_DONE)
  280.         return(this);
  281.     else
  282.         return(NULL);
  283.  
  284. }
  285.  
  286.  
  287.  
  288. /*---------------------------- help screen ----------------------------------*/
  289. void show_help(int h)
  290. {
  291.  
  292.     char *type[] = {"New Group",  "Thread",  "Article"};
  293.  
  294.     textbackground(helpb);    textcolor(helpf);
  295.     clrscr();
  296.     textbackground(headb);    textcolor(headf);
  297.     clreol();
  298.     cprintf("         %s Help  (%s)\r\n", type[h], VERSION);
  299.     clreol();
  300.     textbackground(helpb);    textcolor(helpf);
  301.  
  302.     switch (h) {
  303.         case HELP_GROUP   :
  304.  
  305.     cprintf("\r\n\r\n");
  306.     cprintf("   LIST NEWSGROUPS                     CHOOSING NEWSGROUPS\r\n\r\n");
  307.     cprintf("   PgUp  move display up one page